# Define directories and other variables
RELEASE_DIR = bin
RELEASE_LIB_DIR = lib
BUILD_CACHE_DIR = build_cache

EXAMPLE_SUB_DIR = case_01 case_02 case_03 case_04
EXAMPLE_DIR = $(addprefix $(BUILD_CACHE_DIR)/, $(EXAMPLE_SUB_DIR))

RELEASE_NAMES = $(addprefix $(RELEASE_DIR)/, $(EXAMPLE_SUB_DIR))
RELEASE_LIBS = $(RELEASE_LIB_DIR)/libxncc_log_static.a $(RELEASE_LIB_DIR)/libxncc_log.so

CPP_STANDARD = -std=c++14
CXX = g++
COMPILE_FLAGS = -g -O3\
    -Wall \
    -Wextra \
    -Werror \
    -Wconversion \
    -Wno-stringop-truncation \
    -Wno-format-truncation \
    -Wno-unused-parameter \
    -Wno-unused-function \
    -Wold-style-cast \
    -Woverloaded-virtual \
    -Wpointer-arith \
    -Wwrite-strings \
    -rdynamic \
    -pthread -MMD -MP 

INCLUDE_DIR = -I include -I async_log/inc

# Define object files and dependencies
FILE_NAMES = AsyncLogQueue Common Logger LoggerEngine LoggerFile
OBJS = $(foreach obj, $(FILE_NAMES), $(BUILD_CACHE_DIR)/$(obj).o)
SHARED_OBJS =$(foreach obj, $(FILE_NAMES), $(BUILD_CACHE_DIR)/$(obj).pic.o)

EXAMPLE_OBJS =$(foreach obj, $(EXAMPLE_SUB_DIR), $(BUILD_CACHE_DIR)/$(obj)/main.o)

# Rules
all: $(RELEASE_LIBS) $(RELEASE_NAMES)
	@echo "Build complete."
	@echo "Run ./bin/case* to see the result."


DEPENDS := $(foreach objs, $(OBJS), $(patsubst %.o, %.d, $(objs)))
DEPENDS += $(foreach objs, $(EXAMPLE_OBJS), $(patsubst %.o, %.d, $(objs)))


test:
	@echo $(EXAMPLE_DIR) $(OBJS) $(RELEASE_NAMES) $(EXAMPLE_OBJS) $(DEPENDS)
	@mkdir -p $(EXAMPLE_DIR)
# Library rules
$(RELEASE_LIB_DIR)/libxncc_log_static.a : $(OBJS) 
	ar rcs $@ $^

$(RELEASE_LIB_DIR)/libxncc_log.so : $(SHARED_OBJS)
	$(CXX) -shared -fPIC $(CPP_STANDARD) $(COMPILE_FLAGS) $(INCLUDE_DIR) -o $@ $^


$(BUILD_CACHE_DIR)/%.d: ;
$(BUILD_CACHE_DIR)/%/%.d: ;
# Example executables
$(RELEASE_DIR)/%: $(BUILD_CACHE_DIR)/%/main.o $(RELEASE_LIB_DIR)/libxncc_log_static.a
	$(CXX) $(CPP_STANDARD) $(COMPILE_FLAGS) $(INCLUDE_DIR) -o $@ $^

# Object file rules
$(BUILD_CACHE_DIR)/%.o: async_log/src/%.cpp $(BUILD_CACHE_DIR)/%.d Makefile  $(BUILD_CACHE_DIR) $(RELEASE_LIB_DIR) $(RELEASE_DIR) $(EXAMPLE_DIR)
	$(CXX) $(CPP_STANDARD) $(COMPILE_FLAGS) $(INCLUDE_DIR) -o $@ -c $<
	@echo "Compile $@"

$(BUILD_CACHE_DIR)/%.pic.o: async_log/src/%.cpp $(BUILD_CACHE_DIR)/%.d Makefile
	$(CXX) -shared -fPIC $(CPP_STANDARD) $(COMPILE_FLAGS) $(INCLUDE_DIR) -o $@ -c $<
	@echo "Compile $@"

$(BUILD_CACHE_DIR)/%/main.o: examples/%/main.cpp $(BUILD_CACHE_DIR)/%/main.d Makefile
	$(CXX) $(CPP_STANDARD) $(COMPILE_FLAGS) $(INCLUDE_DIR) -o $@ -c $<
	@echo "Compile $@"

# 保留中间文件
.PRECIOUS: $(BUILD_CACHE_DIR)/%/main.o

# Directory creation rule
$(BUILD_CACHE_DIR) $(RELEASE_LIB_DIR) $(RELEASE_DIR) $(EXAMPLE_DIR):
	@mkdir -p $@


clean:
	rm -rf $(BUILD_CACHE_DIR) $(RELEASE_DIR) $(RELEASE_LIB_DIR)

ifeq ($(filter $(MAKECMDGOALS), clean test pre), )
-include $(DEPENDS)
endif